import {
  Tree,
  Modal,
  Form,
  Input,
  message,
  Button,
  Space,
  Typography,
  Table,
  Popconfirm,
  Upload,
} from 'antd'
import React, { useState, useEffect, useRef, useImperativeHandle } from 'react'
import {
  pageQueryProject,
  projectInsert,
  projectUpdate,
  projectDelete,
  projectInfo,
} from '@/api/project.js'
import { cloneDeep } from 'lodash'
import {
  PlusOutlined,
  DeleteOutlined,
  FolderOpenOutlined,
  CloseOutlined,
  EditOutlined,
  ToTopOutlined,
  CloudUploadOutlined,
  CloudDownloadOutlined,
} from '@ant-design/icons'
import { ProjectFlowEditModal } from '../project-flow/index.jsx'
import { projectFlowDelete, exportProject, exportFlow, importFlow } from '@/api/project-flow.js'
import './index.less'
import { downloadTextFile } from '@/utils'

const { Text } = Typography

const getTreeIdList = (treeData) => {
  const treeIdList = []
  treeData = treeData || []
  treeData.forEach((item) => {
    treeIdList.push(item.id)
    if (item.children) {
      treeIdList.push(...getTreeIdList(item.children))
    }
  })
  return treeIdList
}

const ProjectTree = React.forwardRef((props, ref) => {
  const { onSelect, onRightClick, selectItem } = props

  const treeMap = {}

  const fieldNames = {
    title: 'name',
    key: 'id',
    children: 'children',
  }

  const [treeData, setTreeData] = useState([])

  const [expandedKeys, setExpandedKeys] = useState([])

  useImperativeHandle(
    ref,
    () => ({
      onAddProject() {
        onAdd()
      },
      onOpenProject() {
        onOpen()
      },
    }),
    []
  )

  const [editData, setEditData] = useState(null)

  const onOpen = () => {
    setSelectVisible(true)
  }

  const onXml = (node) => {
    exportProject({ projectId: node.id }).then(() => {
      message.success('生成XML成功')
    })
  }

  const onAdd = () => {
    setEditData({})
  }

  const onEdit = (data) => {
    setEditData({
      id: data.id,
      projectName: data.name,
      projectPath: data.projectPath,
    })
  }

  const onDelete = (data) => {
    projectDelete(data).then(() => {
      message.success('删除成功')
    })
  }

  const onCloseProject = (data) => {
    let index = treeData.findIndex((item) => item.id === data.id)
    if (index !== -1) {
      treeData.splice(index, 1)
      setTreeData([...treeData])
    }
  }

  const onSuccess = (projectData) => {
    if (editData && editData.id) {
      let project = treeData.find((item) => item.id == editData.id)
      project.name = projectData.projectName
      project.projectPath = projectData.projectPath
      setTreeData([...treeData])
      setEditData(null)
    } else {
      projectData.children.forEach(item => {
        item.projectId = projectData.id
      })
      projectData.selectable = false
      let tempData = [...treeData, projectData]
      setTreeData(tempData)
      setExpandedKeys(getTreeIdList(tempData))
    }
  }

  const onClose = () => {
    setEditData(null)
  }

  const onTreeSelect = (selectedKeys, info) => {
    if (info.selectedNodes.length > 0) {
      onSelect(info.selectedNodes[0])
    }
  }

  const [selectVisible, setSelectVisible] = useState(false)
  const onSelectProject = (project) => {
    if (treeData.find((item) => project.id === item.id)) {
      return
    }

    projectInfo({ projectId: project.id }).then((res) => {
      onSuccess(res.data)
    })
  }

  const [editFlowData, setEditFlowData] = useState(null)
  const onFlowSuccess = (flow) => {
    if (editFlowData && editFlowData.id) {
      let project = treeData.find((item) => item.id == editFlowData.projectId)
      let flowData = project.children.find(item => item.id == editFlowData.id)
      flowData.name = flow.flowName
      setTreeData([...treeData])
      setEditFlowData(null)
    } else {
      let project = treeData.find((item) => flow.project_id === item.id)
      flow.projectId = project.id
      project.children.push(flow)
      setTreeData([...treeData])
      setEditFlowData(null)
    }
  }

  const onFlowEdit = (flowData) => {
    flowData = {
      id: flowData.id,
      flowName: flowData.name,
      projectId: flowData.projectId
    }
    setEditFlowData(flowData)
  }

  const onDeleteFlow = (flowData) => {
    projectFlowDelete({ id: flowData.id }).then(() => {
      message.success('删除成功')
      let project = treeData.find((item) => item.id == flowData.projectId)
      let index = project.children.findIndex(item => item.id == flowData.id)
      project.children.splice(index, 1)
      setTreeData([...treeData])

      if (selectItem && selectItem.id == flowData.id) {
        onSelect(null)
      }
    })
  }

  const onFlowClose = () => {
    setEditFlowData(null)
  }

  const stopPropagation = (e) => {
    e.stopPropagation()
  }

  const onExport = async ({ id, name, projectId }) => {
    const res = await exportFlow({ flowId: id, projectId })
    downloadTextFile(JSON.stringify(res), name)
  }

  const uploadProps = {
    name: 'file',
    action: '/api/step/importFlow',
    accept: '.txt',
    maxCount: 1,
    showUploadList: false,
    onChange(info) {
      if (info.file.status !== 'uploading') {
        // console.log(info.file, info.fileList);
      }
      if (info.file.status === 'done') {
        console.log(info.file.response.data)
        onFlowSuccess(info.file.response.data)
        message.success(`${info.file.name} 上传成功`)
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 上传失败`)
      }
    },
  }

  const titleRender = (node) => {
    treeMap[node.id] = node
    return (
      <div className="flex-row">
        <Text className="flex-1" ellipsis={true}>
          {node.name}
        </Text>
        {node.config_type == '0' && (
          <Space className="flex-shrink" size={2} onClick={stopPropagation}>
            <Button
              className="icon-btn"
              title="生成XML"
              size="small"
              type="text"
              icon={<ToTopOutlined />}
              onClick={() => onXml(node)}
            />
            <Button
              className="icon-btn"
              title="编辑工程"
              size="small"
              type="text"
              icon={<EditOutlined />}
              onClick={() => onEdit(node)}
            />
            <Popconfirm
              title="删除提示"
              description="确认删除当前工程?"
              onConfirm={() => onDelete(node)}
              okText="确认"
              cancelText="取消"
            >
              <Button
                className="icon-btn"
                title="删除工程"
                size="small"
                type="text"
                icon={<DeleteOutlined />}
              />
            </Popconfirm>
            <Popconfirm
              title="删除提示"
              description="确认关闭当前工程?"
              onConfirm={() => onCloseProject(node)}
              okText="确认"
              cancelText="取消"
            >
              <Button
                className="icon-btn"
                title="关闭工程"
                size="small"
                type="text"
                icon={<CloseOutlined />}
              />
            </Popconfirm>
            <Button
              className="icon-btn"
              title="添加流程"
              size="small"
              type="text"
              icon={<PlusOutlined />}
              onClick={() => setEditFlowData({ projectId: node.id })}
            />
            <Upload {...uploadProps} data={{ projectId: node.id }}>
              <Button
                className="icon-btn"
                title="导入流程"
                size="small"
                type="text"
                icon={<CloudDownloadOutlined />}
              />
            </Upload>
          </Space>
        )}
        {node.config_type == '6' && (
          <Space className="flex-shrink" size={2} onClick={stopPropagation}>
            <Button
              className="icon-btn"
              type="text"
              title='导出流程'
              icon={<CloudUploadOutlined />}
              size="small"
              onClick={() => onExport(node)}
            />
            <Button
              className="icon-btn"
              title="编辑流程"
              size="small"
              type="text"
              icon={<EditOutlined />}
              onClick={() => onFlowEdit(node)}
            />
            <Popconfirm
              title="删除提示"
              description="确认删除当前流程?"
              onConfirm={() => onDeleteFlow(node)}
              okText="确认"
              cancelText="取消"
            >
              <Button
                className="icon-btn"
                title="删除工程"
                size="small"
                type="text"
                icon={<DeleteOutlined />}
              />
            </Popconfirm>
          </Space>
        )}
      </div>
    )
  }

  return (
    <div className="project-tree">
      <Tree
        expandedKeys={expandedKeys}
        fieldNames={fieldNames}
        blockNode={true}
        treeData={treeData}
        defaultExpandAll
        titleRender={titleRender}
        onSelect={onTreeSelect}
        onRightClick={onRightClick}
      />
      <ProjectEditModal
        initData={editData}
        onSuccess={onSuccess}
        onClose={onClose}
      />
      <ProjectSelectModal
        visible={selectVisible}
        onSelect={onSelectProject}
        onClose={() => setSelectVisible(false)}
      />
      <ProjectFlowEditModal
        initData={editFlowData}
        onSuccess={onFlowSuccess}
        onClose={onFlowClose}
      />
    </div>
  )
})

export const ProjectEditModal = (props) => {
  const { initData, onSuccess, onClose } = props
  const formRef = useRef()

  const [modalData, setModalData] = useState({
    key: Date.now(),
    visible: false,
    confirmLoading: false,
    formData: null,
    rules: {
      projectName: [{ required: true, message: '请输入工程名称' }],
    },
  })

  const onEdit = (data) => {
    data = data && data.id ? data : { projectName: '', projectPath: '' }

    setModalData({
      ...modalData,
      formData: data,
      visible: true,
    })
    if (formRef.current) {
      formRef.current.setFieldsValue(data)
    }
  }

  const onOk = () => {
    formRef.current.validateFields().then((value) => {
      let submitData = cloneDeep(value)
      let menthod = projectInsert
      if (modalData.formData.id) {
        menthod = projectUpdate
      }
      setModalData({
        ...modalData,
        confirmLoading: true,
      })
      submitData = { ...modalData.formData, ...submitData }
      menthod(submitData).then((res) => {
        onSuccess(res.data || submitData)
        onClose()
        message.success('保存成功')
        setModalData({
          ...modalData,
          visible: false,
          confirmLoading: false,
        })
      }).catch(() => {
        setModalData({
          ...modalData,
          confirmLoading: false
        })
      })
    })
  }

  const onCancel = () => {
    setModalData({
      ...modalData,
      visible: false,
    })
    onClose()
  }

  useEffect(() => {
    if (initData) {
      onEdit(initData)
    }
  }, [initData])

  const getDir = async () => {
    const projectPath = window.GetLocalDir()
    formRef.current.setFieldsValue({ projectPath })
  }

  return (
    <Modal
      centered
      title={
        modalData.formData && modalData.formData.id ? '编辑工程' : '新增工程'
      }
      confirmLoading={modalData.confirmLoading}
      open={modalData.visible}
      onOk={onOk}
      onCancel={onCancel}
    >
      <Form
        ref={formRef}
        layout="vertical"
        className='project-form'
        initialValues={modalData.formData}
      >
        <Form.Item
          label="工程名称"
          name="projectName"
          rules={modalData.rules.projectName}
        >
          <Input placeholder="请输入工程名称" autoComplete='off' />
        </Form.Item>
        <Form.Item
          label="工程路径"
          name="projectPath"
          rules={modalData.rules.projectPath}
        >
          <Input placeholder="请选择工程路径" autoComplete='off' addonAfter={<Button
            className='select-folder'
            type="primary"
            onClick={getDir}
            icon={<FolderOpenOutlined />}
          ></Button>} />
        </Form.Item>
      </Form>
    </Modal>
  )
}

const ProjectSelectModal = (props) => {
  const { visible, onClose, onSelect } = props

  const columns = [
    {
      title: '工程名称',
      dataIndex: 'projectName',
      key: 'projectName',
    },
  ]

  const [tabelData, setTableData] = useState([])
  const requestList = () => {
    pageQueryProject({ pageSize: 1000 }).then((res) => {
      setTableData(res.data.pageInfo.list)
    })
  }

  let selectRow = null

  const onOk = () => {
    if (!selectRow) {
      return message.error('请选择项目')
    }
    onSelect(selectRow)
    onClose()
  }

  const rowSelection = {
    type: 'radio',
    onChange: (selectedRowKeys, selectedRows) => {
      selectRow = selectedRows[0]
    },
  }

  const tableProps = {
    scroll: {
      y: 400,
    },
  }

  useEffect(() => {
    if (visible) {
      selectRow = null
      requestList()
    }
  }, [visible])

  return (
    <Modal centered title="选择工程" open={visible} onOk={onOk} onCancel={onClose}>
      <Table
        rowKey="id"
        rowSelection={rowSelection}
        dataSource={tabelData}
        columns={columns}
        pagination={false}
        {...tableProps}
      />
    </Modal>
  )
}

ProjectTree.displayName = 'ProjectTree'

export default ProjectTree
